Spring WebFlux 애플리케이션 서버에서 요청이 처리되는 과정
Spring WebFlux는 JVM 위에서 확장 가능한 웹 애플리케이션을 만들기 위한 논블로킹, 리액티브 웹 스택입니다. 전체적인 흐름은 전통적인 Spring MVC와 유사한 부분도 있지만, 완전 비동기 이벤트 기반 아키텍처를 사용하기 때문에 기반 엔진, 요청 처리 및 동시성 모델이 근본적으로 다릅니다.
아래는 Spring WebFlux 애플리케이션 서버 내에서 HTTP 요청이 처리되는 단계별 과정입니다.
1. 요청 진입: Netty 또는 서블릿 컨테이너 (Reactor Netty, Tomcat 등)
- 애플리케이션은 보통 기본값으로 Reactor Netty 서버 위에서 구동되지만, Undertow나 Servlet 3.1 이상 비동기 지원 컨테이너도 사용할 수 있습니다.
- 네트워크 스레드가 경량, 논블로킹 방식으로 요청을 수신합니다.
- 요청은 리액티브 서버 요청 객체(
ServerHttpRequest)로 래핑됩니다.
2. 필터 체인 (WebFilter)
- WebFilter(서블릿 필터의 리액티브 버전)가 본격적인 라우팅 전에 요청을 처리합니다.
- 사용 사례: CORS 처리, 인증, 로깅, 헤더 변조 등
- 필터들은 논블로킹 방식으로 요청을 변경하거나, 중단하거나, 장식할 수 있습니다.
3. 프론트 컨트롤러: DispatcherHandler
- Spring MVC의
DispatcherServlet과 비슷한 역할을 하는 완전 논블로킹 DispatcherHandler가 모든 요청을 조율하고 라우팅합니다.
4. 라우터 함수 또는 핸들러 매핑
- 요청 라우팅 방식:
- 애노테이션 기반:
@RequestMapping,@GetMapping등 MVC와 동일함 - 함수형 라우팅:
RouterFunction,HandlerFunction를 사용 (Node.js Express 스타일 유사)
- 애노테이션 기반:
- HandlerMapping이 요청에 맞는 핸들러(컨트롤러 또는 함수)를 찾아냅니다.
5. 핸들러 어댑터와 인자 해석
- HandlerAdapter가 핸들러 메서드 호출 방식을 선택합니다.
- 경로 변수, 쿼리 파라미터, 헤더, 요청 바디 등을 추출해줍니다.
- 모든 메서드 인자 해석은 요청 데이터를 스트림(
Publisher,Mono,Flux) 형태로 읽는 논블로킹 방식으로 수행됩니다.
6. 핸들러(컨트롤러 또는 함수) 실행
- 매칭된 핸들러가 요청을 처리합니다:
- 메서드는 일반 객체 대신
Mono<ResponseType>,Flux<ResponseType>같은 리액티브 타입을 반환합니다. - 비즈니스 로직, DB 호출, 외부 서비스 통신도 모두 논블로킹 리액티브 API로 처리됩니다.
- 메서드는 일반 객체 대신
- I/O 완료나 데이터 준비를 기다리면서 스레드를 블로킹하지 않고, 데이터가 흐름에 따라 연산이 계속됩니다.
7. 예외 처리
- 에러와 예외는 리액티브 스트림 내 “에러 신호”로 전달됩니다.
- 예외 처리기(
@ExceptionHandler, 글로벌WebExceptionHandler)가 이 신호를 잡아 리액티브 방식으로 에러 응답을 생성합니다.
8. 응답 준비
- 컨트롤러는 응답 본문, HTTP 상태 코드, 뷰 이름 등으로 응답을 반환합니다.
- 메시지 작성기(예: JSON용 Jackson, 템플릿 엔진 Thymeleaf 등)가 논블로킹 방식으로 데이터가 도착하는 대로 시리얼라이즈 또는 렌더링합니다.
9. WebFilter (후처리)
- 응답에 대해 아웃바운드 필터가 비동기로 데코레이트, 수정, 압축, 로깅 등을 수행할 수 있습니다.
10. 응답 전송
- 논블로킹 서버가 데이터를 준비되는대로 클라이언트로 스트리밍하여 씁니다.
- Netty, Undertow, 서블릿 컨테이너는 이벤트 기반으로 비동기 네트워크 소켓을 통해 데이터를 전송합니다.
- 커넥션은 효율적으로 논블로킹 방식으로 해제되어, 수많은 동시 연결을 처리합니다.
요약 표: Spring WebFlux 내부 요청 처리 과정
| 단계 | 주요 컴포넌트 | 주요 내용/특징 |
|---|---|---|
| 요청 진입 | Netty/Undertow/Servlet 어댑터 | 논블로킹, 리액티브 래퍼 |
| 사전 처리 | WebFilter | 인증, CORS, 로깅 등 |
| 라우팅 | DispatcherHandler + HandlerMapping | URL·메서드에 맞는 핸들러 매핑 |
| 핸들러 실행 | 컨트롤러/함수 | Mono/Flux 반환, 비동기 로직 |
| 예외 처리 | WebExceptionHandler | 리액티브 스트림 에러 처리 |
| 응답 직렬화 | 메시지 작성기, 템플릿 엔진 | 논블로킹 응답 생성 |
| 후처리 | WebFilter | 응답 후 아웃바운드 필터링 |
| 응답 송출 | Netty/Servlet 비동기 전송 | 클라이언트에 비동기 데이터 스트림 |
Spring MVC와의 주요 차이점
- 스레드 모델
Spring WebFlux는 요청당 스레드 블로킹이 전혀 없으며, 소수 스레드(이벤트 루프 모델)로 수천 건 동시 요청 처리 가능. - 리액티브 타입
핸들러가Mono나Flux를 반환하여 스트리밍, 백프레셔, 비동기 I/O 전반이 가능. - 엔드-투-엔드 논블로킹
네트워크, 필터, 핸들러, DB 호출, 응답 전송 모두 비동기/논블로킹 처리 가능(지원할 경우). - 적합한 케이스
높은 동시성, 실시간 API(채팅, 스트리밍, IoT 등) 또는 대기 기반 비동기 작업에 이상적.
요약하자면:
Spring WebFlux 서버는 각 요청을 비동기 신호 흐름으로 처리하며, I/O에 스레드를 블로킹하지 않고 대규모 확장성과 유연성을 제공합니다.